package me.mononin.common.common.widget;


import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import me.mononin.common.R;
import me.mononin.common.common.widget.recycler.RecyclerAdapter;

public class GalleryView extends RecyclerView {

    private static final int LOADER_ID = 0x0100;
    private static final int IMAGE_MAX_SELECT = 6;
    private static final int MIN_IMAGE_FILE_SIZE = 10 * 1024;
    private GalleryAdapter mAdapter;
    private LoaderCallback mLoaderCallback = new LoaderCallback();
    private List<Image> images = new LinkedList<>();
    private SelectedChangeListener mListener;

    public GalleryView(Context context) {
        super(context);
        init();
    }

    public GalleryView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 初始化GalleryLayout
     */
    private void init() {
        mAdapter = new GalleryAdapter();
        setLayoutManager(new GridLayoutManager(getContext(), 4));
        setAdapter(mAdapter);
        mAdapter.setListener(new RecyclerAdapter.AdapterListenerImpl<Image>() {
            @Override
            public void onItemClick(RecyclerAdapter.ViewHolder holder, Image image) {
                // Cell点击操作，如果说我们的点击是允许的，那么更新对应的Cell的状态
                // 然后更新界面，同理；如果说不能允许点击（已经达到最大的选中数量）那么就不刷新界面
                if (onItemSelectClick(image)) {

                    holder.updateBind(image);
                }
            }
        });
    }

    /**
     * 判断点击事件的合法性，并返回
     *
     * @param image 点击时的图片资源
     * @return 当点击事件合法化时，并处理后，返回True，反之，返回False
     */
    private boolean onItemSelectClick(Image image) {

        boolean isRefresh = false;
        //判断图片是否已经选中
        if (images.contains(image)) {
            images.remove(image);
            isRefresh = true;
            image.isChecked = false;
        } else {
            //判断选中图片是否超过最大值
            if (images.size() >= IMAGE_MAX_SELECT) {
                //对Toast内容进行格式化
                String tip = getResources().getString(R.string.tip_select_portrait);
                tip = String.format(tip, IMAGE_MAX_SELECT);
                //Toast提醒
                Toast.makeText(getContext(), tip, Toast.LENGTH_SHORT).show();
                isRefresh = false;
            } else {
                //使图片变更为选中
                images.add(image);
                isRefresh = true;
                image.isChecked = true;
            }


        }
        //选中状态改变时
        //通知外部调用者刷新状态
        if (isRefresh) {
            notifySelectChange();
        }

        return true;
    }

    /**
     * Loader管理器初始化
     * @param loaderManager loader管理器
     * @return 返回一个loaderID，用于外部调用销毁
     */
    public int setup(LoaderManager loaderManager, SelectedChangeListener listener) {
        mListener = listener;
        loaderManager.initLoader(LOADER_ID, null, mLoaderCallback);
        return LOADER_ID;
    }

    /**
     * 获取选中状态下的图片路径
     *
     * @return 返回选中状态下图片路径
     */
    public String[] getSelectedPath() {
        String path[] = new String[images.size()];
        int index = 0;
        for (Image image : images) {
            path[index++] = image.path;
        }

        return path;
    }

    /**
     * 清空数据
     */
    public void clear() {

        for (Image image : images) {
            //改变状态
            image.isChecked = false;
        }
        //清空数据
        images.clear();
        //通知更新
        mAdapter.notifyDataSetChanged();
    }

    /**
     * 用于通知外部调用者
     * 选中状态已经改变
     */
    private void notifySelectChange() {
        SelectedChangeListener listener = mListener;
        if (listener!=null){
            listener.onSelectedCountChanged(images.size());
        }
    }


    /**
     * 继承封装好的RecyclerAdapter
     * 定义真正上使用的Adapter适配器
     */
    private class GalleryAdapter extends RecyclerAdapter<Image> {

        @Override
        protected ViewHolder<Image> onCreateViewHolder(View view, int viewType) {
            //创建ViewHolder
            return new GalleryHolder(view);
        }

        @Override
        protected int getItemViewType(int position, Image image) {
            return R.layout.gallery_item_view;
        }
    }

    /**
     * 定义具体需要显示的Image类
     */
    private static class Image {
        int id;
        String path;
        long dateTime;
        boolean isChecked;

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Image image = (Image) o;

            return path != null ? path.equals(image.path) : image.path == null;
        }

        @Override
        public int hashCode() {
            return path != null ? path.hashCode() : 0;
        }
    }

    /**
     * 用于实际加载数据LoaderCallback
     */
    private class LoaderCallback implements LoaderManager.LoaderCallbacks<Cursor> {

        private final String[] IMAGE_PROJECTION = new String[]{
                MediaStore.Images.Media._ID, // Id
                MediaStore.Images.Media.DATA, // 图片路径
                MediaStore.Images.Media.DATE_ADDED // 图片的创建时间ø
        };

        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            //创建Loader完成时返回

            if (id == LOADER_ID) {
                return new CursorLoader(getContext(),
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        IMAGE_PROJECTION,
                        null,
                        null,
                        IMAGE_PROJECTION[2] + " DESC");
            }
            return null;
        }


        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            //当Loader加载完时
            List<Image> images = new ArrayList<>();
            //判断是否有数据
            if (data != null) {
                int count = data.getCount();
                if (count > 0) {
                    //移动到游标开始位置
                    data.moveToFirst();
                    //获取当前位置所对应index信息
                    int indexId = data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]);
                    int indexPath = data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]);
                    int indexTime = data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]);

                    do {
                        //提取信息
                        int id = data.getInt(indexId);
                        String path = data.getString(indexPath);
                        Long addTime = data.getLong(indexTime);

                        File file = new File(path);
                        if (!file.exists() || file.length() < MIN_IMAGE_FILE_SIZE) {
                            // 如果没有图片，或者图片大小太小，则跳过
                            continue;
                        }

                        //生成Image实例
                        Image image = new Image();
                        image.id = id;
                        image.path = path;
                        image.dateTime = addTime;
                        //添加图片资源信息
                        images.add(image);

                    } while (data.moveToNext());
                }
            }
            //更新图片资源信息
            updateSource(images);
        }

        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            //当Loader重置或者销毁时触发
            updateSource(null);
        }
    }


    /**
     * 定义具体需要使用的ViewHolder
     * 其为GalleryHolder
     */
    private class GalleryHolder extends RecyclerAdapter.ViewHolder<Image> {

        private ImageView mImage;
        private CheckBox mCheckBox;
        private View mShadow;

        public GalleryHolder(View itemView) {
            super(itemView);
            mImage = itemView.findViewById(R.id.gallery_img);
            mCheckBox = itemView.findViewById(R.id.gallery_cb);
            mShadow = itemView.findViewById(R.id.gallery_v);
        }

        @Override
        protected void onBind(Image image) {
            Glide.with(getContext())  //获取上下文
                    .load(image.path) //
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .centerCrop()
                    .placeholder(R.color.grey_200)
                    .into(mImage);

            mShadow.setVisibility(image.isChecked ? VISIBLE : INVISIBLE);
            mCheckBox.setChecked(image.isChecked);
            mCheckBox.setVisibility(VISIBLE);
        }
    }

    private void updateSource(List<Image> images) {
        mAdapter.replace(images);
    }

    /**
     * 对外的一个监听器
     */
    public interface SelectedChangeListener {
        void onSelectedCountChanged(int count);
    }

}
